// -----------------------------------------------------------------------
//  <copyright file="DeleteRoleCommand.cs" company="LiuliuSoft">
//      Copyright (c) 2022-2024 DaprPlus. All rights reserved.
//  </copyright>
//  <site>https://dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2024/12/10 14:34:26</last-date>
// -----------------------------------------------------------------------

using DaprPlus.Identity.Domain.Entities;
using DaprPlus.Identity.Domain.IntegrationEvents;


namespace DaprPlus.Identity.Application.Identity.Roles.Commands;

[AuthConfig(typeof(Role), ResourceAccessType.RoleLimit, "Delete")]
public class DeleteRoleCommand(long[] ids) : IRequest<ApiResult>, ICommand
{
    public long[] Ids { get; } = ids;
}

public class DeleteRoleCommandHandler(IServiceProvider provider)
    : IRequestHandler<DeleteRoleCommand, ApiResult>
{
    public async Task<ApiResult> Handle(DeleteRoleCommand request, CancellationToken cancellationToken)
    {
        var repository = provider.GetRepository<Role>();
        var spec = new RoleByIdsSpec<Role>(request.Ids);
        var count = await repository.DeleteBatchAsync(spec, cancellationToken);
        if (count > 0)
        {
            var uow = provider.GetUnitOfWork();
            uow.AddIntegrationEvent(new RoleDeletedIntegrationEvent(request.Ids));
        }

        return ApiResult.SuccessOrNoChanged(count > 0, $"{count}个角色信息删除成功");
    }
}

public class DeleteRoleCommandValidator : AbstractValidator<DeleteRoleCommand>
{
    public DeleteRoleCommandValidator(IServiceProvider provider)
    {
        ClassLevelCascadeMode = CascadeMode.Stop;
        RuleLevelCascadeMode = CascadeMode.Stop;

        RuleFor(m => m.Ids).NotEmpty().WithMessage("请选择要删除的角色")
            .CustomAsync(async (ids, context, token) =>
            {
                var spec = new RoleByIdsSpec<Role>(ids);
                var roleRepository = provider.GetRepository<Role>();
                var userRoleRepository = provider.GetQueryRepository<UserRole>();

                var roles = await roleRepository.GetAllAsync(spec, m => new
                {
                    m.Id,
                    m.Name,
                    m.IsSystem,
                    m.IsDefault
                }, token);
                foreach (var role in roles)
                {
                    if (role.IsSystem)
                    {
                        context.AddFailure($"角色 {role.Name} 是系统角色，不能删除");
                        return;
                    }
                    if (role.IsDefault)
                    {
                        context.AddFailure($"角色 {role.Name} 是默认角色，不能删除");
                        return;
                    }
                    var userRoleSpec = new UserRoleByRoleSpec<UserRole>(role.Id);
                    var anyUserRole = await userRoleRepository.AnyAsync(userRoleSpec, token);
                    if (anyUserRole)
                    {
                        context.AddFailure($"角色 {role.Name} 已被用户使用，不能删除");
                    }
                }
            });
    }
}


